<template>
  <div>
    <div id="map" style="width: 100vw; height: 100vh"></div>
    <canvas id="mapBgCanvas" style="position: fixed"></canvas>
  </div>
</template>

<script>
import * as Cesium from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
import mapData from "@/assets/data/map.js";
import famen from "@/assets/famen.gltf"

export default {
  name: "cesium",
  data() {
    return {
      viewer: null,
      entity_point_list: {},
      entity_line_list: {},
      entity_polygon: null,
      primitive_point_list: {},
      primitive_line_list: {},
      primitive_polygon: null,
      primitive_polygonOutline: null,
      gradientColor: null,
    };
  },
  methods: {
    initMap() {
      Cesium.Ion.defaultAccessToken =
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2ZTgxOGNhZC03NThmLTQ0NzMtOTNlYS1kNmM3YzlmZDU3NTMiLCJpZCI6MTI1NTY3LCJpYXQiOjE2NzY5MDI0MzJ9.ulIEz3NCh2cMEBiHrqIuv9I6icn5KTMMnBdy2wassoM";
      this.viewer = new Cesium.Viewer("map", {
        // 配置项
      });
    },
    // entity加载点
    add_entity_point() {
      mapData.junction_id.forEach((item, index) => {
        this.entity_point_list[item] = this.viewer.entities.add({
          position: Cesium.Cartesian3.fromDegrees(
            mapData.junction_x[index],
            mapData.junction_y[index]
          ),
          point: {
            pixelSize: 5,
            color: new Cesium.Color(20 / 255, 204 / 255, 137 / 255, 1),
          },
          name: "point",
        });
      });
    },
    // entity添加线
    add_entity_line() {
      mapData.pipe_id.forEach((item, index) => {
        this.entity_line_list[item] = this.viewer.entities.add({
          polyline: {
            positions: Cesium.Cartesian3.fromDegreesArray(
              handleData(mapData.pipe_vertices[index])
            ),
            width: 2,
            material: new Cesium.Color(0 / 255, 185 / 255, 255 / 255, 1),
          },
          name: "line",
        });
      });

      function handleData(data) {
        let arr = [];
        data.forEach((item) => {
          arr.push(item[0], item[1]);
        });
        return arr;
      }
    },
    // entity添加面
    add_entity_polygon() {
      this.entity_polygon = this.viewer.entities.add({
        polygon: {
          hierarchy: Cesium.Cartesian3.fromDegreesArray(
            handleData(mapData.polygon_vertices)
          ),
          material: this.gradientColor,
          height: 1000, // 一定要设置高度，否则outline不生效
          outline: true,
          outlineColor: new Cesium.Color(255 / 255, 255 / 255, 255 / 255, 1),
          outlineWidth: 2,
        },
        name: "polygon",
      });

      function handleData(data) {
        let arr = [];
        data.forEach((item) => {
          arr.push(Number(item.x), Number(item.y));
        });
        return arr;
      }
    },
    // primitive添加点
    add_primitive_point() {
      const data = mapData;
      const pointGeometry = [];
      const length = data.junction_id.length;
      for (let index = 0; index <= length - 1; index++) {
        pointGeometry.push(
          new Cesium.GeometryInstance({
            geometry: new Cesium.CircleGeometry({
              center: Cesium.Cartesian3.fromDegrees(
                data.junction_x[index],
                data.junction_y[index]
              ),
              radius: 5,
            }),
            id: { id: data.junction_id[index], name: "point" },
            attributes: {
              color: new Cesium.ColorGeometryInstanceAttribute(
                20 / 255,
                204 / 255,
                137 / 255,
                1
              ),
            },
          })
        );
      }
      this.primitive_point_list = new Cesium.Primitive({
        geometryInstances: pointGeometry,
        appearance: new Cesium.PerInstanceColorAppearance({
          flat: true,
        }),
      });

      this.viewer.scene.primitives.add(this.primitive_point_list);
    },
    // primitive添加线
    add_primitive_line() {
      const data = mapData;
      const lineGeometry = [];
      const length = data.pipe_id.length;
      for (let index = 0; index <= length - 1; index++) {
        lineGeometry.push(
          new Cesium.GeometryInstance({
            geometry: new Cesium.PolylineGeometry({
              positions: Cesium.Cartesian3.fromDegreesArray(
                handleData(data.pipe_vertices[index])
              ),
              width: 2,
            }),
            id: { id: data.pipe_id[index], name: "line" },
            attributes: {
              color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                new Cesium.Color(0 / 255, 185 / 255, 255 / 255, 1)
              ),
            },
          })
        );
      }
      this.primitive_line_list = new Cesium.Primitive({
        geometryInstances: lineGeometry,
        appearance: new Cesium.PolylineColorAppearance(),
      });

      this.viewer.scene.primitives.add(this.primitive_line_list);

      function handleData(data) {
        let arr = [];
        data.forEach((item) => {
          arr.push(item[0], item[1]);
        });
        return arr;
      }
    },
    // primitive添加面
    add_primitive_polygon(
      color = new Cesium.Color(0 / 255, 185 / 255, 255 / 255, 1)
    ) {
      // 多边形
      let polygonGeometry = new Cesium.GeometryInstance({
        geometry: new Cesium.PolygonGeometry({
          height: 1000, // 高度在这里设置
          polygonHierarchy: new Cesium.PolygonHierarchy(
            Cesium.Cartesian3.fromDegreesArray(
              handleData(mapData.polygon_vertices)
            )
          ),
        }),
        id: {
          name: "polygon",
        },
      });
      this.primitive_polygon = new Cesium.Primitive({
        asynchronous: false, // 通过删除再添加实现变色，此过程不会出现卡顿
        geometryInstances: polygonGeometry,
        appearance: new Cesium.EllipsoidSurfaceAppearance({
          material: this.gradientColor,
        }),
      });
      this.viewer.scene.primitives.add(this.primitive_polygon);

      // 多边形边框
      var polygonOutlineGeometry = new Cesium.GeometryInstance({
        geometry: new Cesium.PolylineGeometry({
          positions: Cesium.Cartesian3.fromDegreesArrayHeights(
            handleData(mapData.polygon_vertices, 1000)
          ),
          width: 2,
        }),
        id: {
          name: "polygon",
        },
      });
      this.primitive_polygonOutline = new Cesium.Primitive({
        asynchronous: false,
        geometryInstances: polygonOutlineGeometry,
        appearance: new Cesium.PolylineMaterialAppearance({
          material: Cesium.Material.fromType("Color", {
            color: new Cesium.Color(255 / 255, 255 / 255, 255 / 255, 1),
          }),
        }),
      });
      this.viewer.scene.primitives.add(this.primitive_polygonOutline);

      function handleData(data, height) {
        let arr = [];
        data.forEach((item) => {
          arr.push(Number(item.x), Number(item.y));
          if (height) arr.push(height);
        });
        return arr;
      }
    },
    // 定位
    setView(x, y, z) {
      if (x instanceof Array || y instanceof Array) {
        // 如果x和y是数组，根据x和y计算出定位的矩形范围
        this.viewer.camera.setView({
          destination: Cesium.Rectangle.fromDegrees(...handleData(x, y)),
          duration: 0,
          complete: () => {},
        });
      } else {
        this.viewer.camera.setView({
          destination: Cesium.Cartesian3.fromDegrees(x, y, z),
          duration: 0,
          complete: () => {},
        });
      }

      function handleData(x_arr, y_arr) {
        var xmax = 0;
        var xmin = 180;
        var ymax = 0;
        var ymin = 90;
        x_arr.forEach((x) => {
          xmax = Math.max(xmax, x);
          xmin = Math.min(xmin, x);
        });
        y_arr.forEach((y) => {
          ymax = Math.max(ymax, y);
          ymin = Math.min(ymin, y);
        });
        var shift_x = (xmax - xmin) / 20;
        var shift_y = (ymax - ymin) / 20;
        return [xmin - shift_x, ymin - shift_y, xmax + shift_x, ymax + shift_y];
      }
    },
    // 添加点击事件
    addHandler() {
      const handler = new Cesium.ScreenSpaceEventHandler(
        this.viewer.scene.canvas
      );

      handler.setInputAction((movement) => {
        let pick = this.viewer.scene.pick(movement.position);
        if (!pick) return;
        console.log("pick:", pick);
        // entity
        /*
        if (pick.id.name == "point") {
          pick.id.point.color = new Cesium.Color(
            255 / 255,
            0 / 255,
            0 / 255,
            1
          );
        }
        if (pick.id.name == "line") {
          pick.id.polyline.material.color = new Cesium.Color(
            255 / 255,
            0 / 255,
            0 / 255,
            1
          );
        }
        if (pick.id.name == "polygon") {
          pick.id.polygon.material.color = new Cesium.Color(
            255 / 255,
            0 / 255,
            0 / 255,
            1
          );
        }
        */
        // primitive
        if (pick.id.name == "point") {
          const attributes = pick.primitive.getGeometryInstanceAttributes(
            pick.id
          );
          attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(
            new Cesium.Color(255 / 255, 0 / 255, 0 / 255, 1)
          );
        }
        if (pick.id.name == "line") {
          const attributes = pick.primitive.getGeometryInstanceAttributes(
            pick.id
          );
          attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(
            new Cesium.Color(255 / 255, 0 / 255, 0 / 255, 1)
          );
        }
        if (pick.id.name == "polygon") {
          // 删除图层再重新添加
          pick.primitive.appearance.material.uniforms.color = new Cesium.Color(
            255 / 255,
            0 / 255,
            0 / 255,
            1
          );
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    },
    // 渐变色画布
    initCanvas() {
      var canvas = document.getElementById("mapBgCanvas");
      if (canvas && canvas.getContext) {
        let ctx = canvas.getContext("2d");
        let grad = ctx.createLinearGradient(150, 0, 150, 150); // 创建一个渐变色线性对象
        // grad.addColorStop(0, "rgba(28, 146, 210, 1)"); // 设置渐变颜色
        // grad.addColorStop(1, "rgba(76, 161, 175, 1)");
        grad.addColorStop(0, "rgba(44, 74, 157, 1)"); // 设置渐变颜色
        grad.addColorStop(1, "rgba(33, 184, 255, 1)");
        ctx.fillStyle = grad; // 设置fillStyle为当前的渐变对象
        ctx.fillRect(0, 0, 300, 300); // 绘制渐变图形
      }
      // entity
      this.gradientColor = new Cesium.ImageMaterialProperty({
        image: document.getElementById("mapBgCanvas"),
      });
      // primitive
      // this.gradientColor = new Cesium.Material({
      //   fabric: {
      //     type: "Image",
      //     uniforms: {
      //       image: document.getElementById("mapBgCanvas"),
      //     },
      //   },
      // });
    },
  },
  mounted() {
    this.initCanvas();
    this.initMap();
    this.addHandler();
    // this.add_entity_point();
    // this.add_entity_line();
    this.add_entity_polygon();
    // this.add_primitive_point();
    // this.add_primitive_line();
    // this.add_primitive_polygon();
    this.setView(mapData.junction_x, mapData.junction_y);
  },
};
</script>
